package com.zlq.cn.service.un;

import cn.hutool.core.codec.Base64;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.zlq.cn.config.FinderConfiguration;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.HttpUrl;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.LineIterator;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class ConfigService {
    private static final String BUCKET_NAME = "thirtyfairy";

    private final FinderConfiguration finderConfiguration;

    private final OSS ossClient;

    public ConfigService(FinderConfiguration config) {
        this.finderConfiguration = config;
        ossClient = new OSSClientBuilder()
                .build("https://oss-cn-shenzhen.aliyuncs.com", config.getAliyunAccessKeyId(), config.getAliyunAccessSecret());
    }

    public Map<String, Object> ossSts() {
        Map<String, Object> ossStsDTO = new HashMap<>();
        try {
            // 添加endpoint（直接使用STS endpoint，前两个参数留空，无需添加region ID）
            DefaultProfile.addEndpoint("", "", "Sts", finderConfiguration.getEndpoint());
            // 构造default profile（参数留空，无需添加region ID）
            IClientProfile profile = DefaultProfile.getProfile("", finderConfiguration.getAliyunAccessKeyId(), finderConfiguration.getAliyunAccessSecret());
            // 用profile构造client
            DefaultAcsClient client = new DefaultAcsClient(profile);
            final AssumeRoleRequest request = new AssumeRoleRequest();
            request.setMethod(MethodType.POST);
            request.setRoleArn(finderConfiguration.getRoleArn());
            request.setRoleSessionName(finderConfiguration.getRoleSessionName());
            request.setPolicy(null); // 若policy为空，则用户将获得该角色下所有权限
            request.setDurationSeconds(3600L); // 设置凭证有效时间
            final AssumeRoleResponse response = client.getAcsResponse(request);
            AssumeRoleResponse.Credentials credentials = response.getCredentials();
            log.info("Expiration: " + credentials.getExpiration());
            log.info("Access Key Id: " + credentials.getAccessKeyId());
            log.info("Access Key Secret: " + credentials.getAccessKeySecret());
            log.info("Security Token: " + credentials.getSecurityToken());
            log.info("RequestId: " + response.getRequestId());
            ossStsDTO.put("StatusCode", 200);
            ossStsDTO.put("AccessKeyId", credentials.getAccessKeyId());
            ossStsDTO.put("AccessKeySecret", credentials.getAccessKeySecret());
            ossStsDTO.put("SecurityToken", credentials.getSecurityToken());
            ossStsDTO.put("Expiration", credentials.getExpiration());
        } catch (ClientException e) {
            log.info("Failed：");
            log.info("Error code: " + e.getErrCode());
            log.info("Error message: " + e.getErrMsg());
            log.info("RequestId: " + e.getRequestId());
        }
        return ossStsDTO;
    }

    @SneakyThrows
    public static void main(String[] args) {
//        String s = "https://faceeffect-1254418846.cos.ap-guangzhou.myqcloud.com/ft/SwapGenderPic/1253125261/c8ee9f2b-d23b-4b7e-ad64-f27ba7fc9f23.jpg";
////        String s = "tencentAi" + HttpUrl.get(url).encodedPath();
//        System.out.println(FilenameUtils.getFullPath(s));
//        System.out.println(FilenameUtils.getExtension(s));
//        System.out.println(FilenameUtils.getPathNoEndSeparator(s));
//        System.out.println(FilenameUtils.getExtension(s));
//        System.out.println(FilenameUtils.getFullPath(s) + FilenameUtils.getBaseName(s) + "_head." +FilenameUtils.getExtension(s));
//        System.out.println(s);
//        System.out.println(HttpUrl.get("http://ap-guangzhou.myqcloud.com/tencentAi/textToImage/"+ IdUtil.fastUUID() +".png").encodedPath());
        int startIndex = 1000, endIndex = 1200;
        int index = 0;
        LineIterator it = FileUtils.lineIterator(new File("D:\\download\\服务端\\dldl\\www\\backup\\database\\wow-dldl-center.sql"));
        try {
            while (it.hasNext()) {
                String line = it.nextLine();
                if (startIndex <= index && index <= endIndex)
                    System.out.println(line);
//                    if (line.contains("30000334")) {
//                        System.out.println(line);
//                    }
                index++;
            }
        } finally {
            LineIterator.closeQuietly(it);
        }
    }

    public String putObject(String dir, String beforeImage, String extension, byte[] image) {
        String objectName = dir + HttpUrl.get(beforeImage).encodedPath();
        if (extension != null) {
            objectName = FilenameUtils.getFullPath(objectName) + FilenameUtils.getBaseName(objectName) + extension;
        }
        PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, objectName, new ByteArrayInputStream(image));
        // 设置该属性可以返回response。如果不设置，则返回的response为空。
        putObjectRequest.setProcess("true");
        // 上传字符串。
        PutObjectResult result = ossClient.putObject(putObjectRequest);
        // 如果上传成功，则返回200。
        if (result.getResponse().getStatusCode() == 200) {
            return objectName;
        } else {
            throw new RuntimeException();
        }
    }

    public String putObject(String dir, String image) {
        // 填写Object完整路径，完整路径中不能包含Bucket名称，例如exampledir/exampleobject.txt。
        String objectName = dir + HttpUrl.get(image).encodedPath();
        return putObject(dir, HttpUrl.get(image).encodedPath(), image);
    }

    public String putObject(String dir, String name, String url) {
// 填写Object完整路径，完整路径中不能包含Bucket名称，例如exampledir/exampleobject.txt。
        String objectName = dir + name;
        try (HttpResponse httpResponse = HttpRequest.get(url)
                .setFollowRedirects(true)
                .executeAsync()) {
            log.info("文件上传前链接：" + url);
            log.info("文件上传后链接：" + objectName);
            return putObject(objectName, httpResponse.bodyStream());
        } catch (
                Exception oe) {
            log.info("阿里OSS文件上传失败", oe);
        }
        return null;
    }

    public String putObject(String objectName, InputStream inputStream) {
        try {
            PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, objectName, inputStream);
            // 设置该属性可以返回response。如果不设置，则返回的response为空。
            putObjectRequest.setProcess("true");
            // 上传字符串。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            // 如果上传成功，则返回200。
            if (result.getResponse().getStatusCode() == 200) {
                return objectName;
            } else {
                throw new RuntimeException();
            }
        } catch (Exception oe) {
            log.info("阿里OSS文件上传失败", oe);
        }
        return objectName;
    }

    public List<OSSObjectSummary> listObjects(String keyPrefix) {
        List<OSSObjectSummary> all = new ArrayList<>();
        try {
//        // 设置每页列举200个文件。
            int maxKeys = 200;
            String nextMarker = null;
            ObjectListing objectListing;
            do {
                ListObjectsRequest listObjectsRequest = new ListObjectsRequest(BUCKET_NAME);
                listObjectsRequest.withMarker(nextMarker).withMaxKeys(maxKeys);
                listObjectsRequest.setPrefix(keyPrefix);
                objectListing = ossClient.listObjects(listObjectsRequest);
                all.addAll(objectListing.getObjectSummaries());
                nextMarker = objectListing.getNextMarker();
            } while (objectListing.isTruncated());
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        }
        return all;
    }

    public void deleteObject(String objectName) {
        try {
            // 删除文件或目录。如果要删除目录，目录必须为空。
            ossClient.deleteObject(BUCKET_NAME, objectName);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        }
    }

    public String toBase64(String image) {
        try (HttpResponse httpResponse = HttpRequest.get(image)
                .setFollowRedirects(true)
                .executeAsync()) {
            return Base64.encode(httpResponse.bodyBytes());
        } catch (Exception e) {
            log.info("转换base64失败", e);
        }
        return null;
    }
}
